
package com.hlkj.pay.app.merchant.ext.impl.baofu;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.io.File;
import java.io.IOException;
import java.util.*;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.id.IdUtils;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantReportExtPt;
import com.hlkj.pay.app.merchant.ext.MerchantExtConstant;
import com.hlkj.pay.app.merchant.ext.dto.payment.ChannelVirtualAccountContext;
import com.hlkj.pay.app.merchant.ext.dto.report.*;
import com.hlkj.pay.app.merchant.ext.impl.baofu.dto.BaoFuConfig;
import com.hlkj.pay.app.merchant.ext.impl.baofu.dto.BaoFuReportExtentDto;
import com.hlkj.pay.app.merchant.ext.impl.baofu.dto.BoaFuAppChannelParams;
import com.hlkj.pay.app.merchant.ext.impl.baofu.dto.res.*;
import com.hlkj.pay.app.merchant.ext.impl.baofu.handler.BaoFuMerchantParamsHandle;
import com.hlkj.pay.app.merchant.ext.impl.baofu.handler.BaofuMerchantCommonParamsHandle;
import com.hlkj.pay.app.merchant.ext.impl.baofu.util.BaoFuFileZipUtil;
import com.hlkj.pay.app.merchant.ext.impl.baofu.util.BaoFuSigner;
import com.hlkj.pay.dto.merchant.ReportChannelParamsDto;
import com.hlkj.pay.dto.merchant.report.MerchantReportDto;
import com.hlkj.pay.dto.merchant.report.MerchantReportSmsCodeDto;
import com.hlkj.pay.dto.merchant.report.MerchantReportSmsSendDto;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.enums.PayEnums;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantLicenseDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantReportAmountDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantReportInfoDO;
import com.hlkj.pay.infrastructure.model.pay.PayChannelDictDO;
import com.hlkj.pay.infrastructure.model.pay.PayChannelRequestDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.service.pay.IPayChannelDictService;
import com.hlkj.pay.util.DateUtils;
import com.hlkj.pay.util.HttpRequestUtil;
import com.hlkj.pay.util.MerchantUtils;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/12/20 15:45
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = MerchantExtConstant.CHANNEL_BAOFU)
public class BaofuMerchantReportExtPt implements ChannelMerchantReportExtPt {

    private final BaofuMerchantCommonParamsHandle baofuMerchantCommonParamsHandle;

    private final BaoFuMerchantParamsHandle baoFuMerchantParamsHandle;

    private final IPayChannelDictService payChannelDictService;

    @Override
    public String requestUrl(MerchantReportDto merchantReportDto) {
        return "";
    }

    @Override
    public void merchantReport(ChannelMerchantReportContext channelMerchantReportContext) {
        CommonResult<BaoFuConfig> configCommonResult = baofuMerchantCommonParamsHandle.baoFuConfig(channelMerchantReportContext.getProviderChannelConfig(),
                channelMerchantReportContext.isTest());
        if (!configCommonResult.isSuccess()) {
            channelMerchantReportContext.setRemark(configCommonResult.getMsg());
            channelMerchantReportContext.setProcessStatus(false);
            return;
        }
        // 参数校验
        CommonResult<Void> checkResult = baoFuMerchantParamsHandle.merchantReportParamsCheck(channelMerchantReportContext);
        if (!checkResult.isSuccess()) {
            channelMerchantReportContext.setRemark(checkResult.getMsg());
            channelMerchantReportContext.setProcessStatus(false);
            return;
        }
        BaoFuConfig baoFuConfig = configCommonResult.getData();
        // 先上传文件
        CommonResult<BaoFuCommonRes> commonResult = uploadFile(channelMerchantReportContext, baoFuConfig);
        String fileNo = null;
        if (!commonResult.isSuccess()) {
            channelMerchantReportContext.setRemark(commonResult.getMsg());
            channelMerchantReportContext.setProcessStatus(false);
            return;
        }
        else {
            BaoFuCommonRes data = commonResult.getData();
            if (StringUtils.hasText(data.getData())) {
                fileNo = JsonUtils.parseObject(data.getData(), Map.class).get("file_no").toString();
                ;
            }
            else {
                channelMerchantReportContext.setRemark(data.getResp_msg());
                channelMerchantReportContext.setProcessStatus(false);
            }
        }
        MerchantLicenseDO merchantReportLicense = channelMerchantReportContext.getMerchantReportDto().getMerchantReportLicense();
        List<PayChannelDictDO> payChannelDictList = new ArrayList<>();
        payChannelDictList
                .add(payChannelDictService.queryChannelDict(MerchantExtConstant.CHANNEL_BAOFU, PayEnums.DICT_KEY.AREA_CODE.getCode(), merchantReportLicense.getProvinceCode()));
        payChannelDictList
                .add(payChannelDictService.queryChannelDict(MerchantExtConstant.CHANNEL_BAOFU, PayEnums.DICT_KEY.AREA_CODE.getCode(), merchantReportLicense.getCityCode()));
        payChannelDictList
                .add(payChannelDictService.queryChannelDict(MerchantExtConstant.CHANNEL_BAOFU, PayEnums.DICT_KEY.AREA_CODE.getCode(), merchantReportLicense.getAreaCode()));
        channelMerchantReportContext.setPayChannelDictList(payChannelDictList);

        Map<String, Object> params = baoFuMerchantParamsHandle.merchantReportParams(channelMerchantReportContext);
        params.put("file_no", fileNo);
        params.put("bank_type", baoFuConfig.getBankType());
        String requestId = channelMerchantReportContext.getMerchantReportDto().getMerchantReportInfo().getRequestId();
        PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
        payChannelRequestDO.setRequestParams(JsonUtils.toJsonString(params));
        payChannelRequestDO.setRequestId(requestId);
        payChannelRequestDO.setRequestUrl("2601");
        // 再提交数据
        commonResult = baofuMerchantCommonParamsHandle.request(params, requestId, "2601", channelMerchantReportContext.getNotifyUrl(), baoFuConfig,
                channelMerchantReportContext.isTest());
        payChannelRequestDO.setResponse(JsonUtils.toJsonString(commonResult));
        channelMerchantReportContext.setPayChannelRequestDO(payChannelRequestDO);
        if (!commonResult.isSuccess()) {
            channelMerchantReportContext.setRemark(commonResult.getMsg());
            channelMerchantReportContext.setProcessStatus(false);
            return;
        }
        BaoFuCommonRes baoFuCommonRes = commonResult.getData();
        String data = baoFuCommonRes.getData();
        if (!StringUtils.hasText(data)) {
            channelMerchantReportContext.setRemark(baoFuCommonRes.getResp_msg());
            channelMerchantReportContext.setProcessStatus(false);
            return;
        }
        BaoFuReportSubmitRes baoFuReportSubmitRes = JsonUtils.parseObject(data, BaoFuReportSubmitRes.class);
        MerchantReportDto merchantReportDto = channelMerchantReportContext.getMerchantReportDto();
        MerchantReportInfoDO merchantReportInfo = merchantReportDto.getMerchantReportInfo();
        merchantReportInfo.setSubMchId(baoFuReportSubmitRes.getWallet_no());
        channelMerchantReportContext.setReportStatus(MerchantEnum.REPORT_STATUS.CHANNEL_APPROVE);
    }

    @Override
    public String channelParams(ReportChannelParamsDto accessChannelParamsDto) {
        return "";
    }

    @Override
    public void merchantReportQuery(ChannelMerchantReportQueryContext channelMerchantAccessContext) {
        CommonResult<BaoFuConfig> configCommonResult = baofuMerchantCommonParamsHandle.baoFuConfig(channelMerchantAccessContext.getProviderChannelConfig(),
                channelMerchantAccessContext.isTest());
        if (!configCommonResult.isSuccess()) {
            channelMerchantAccessContext.setRemark(configCommonResult.getMsg());
            channelMerchantAccessContext.setProcessStatus(false);
            return;
        }
        Map<String, Object> params = new HashMap<>();
        MerchantReportInfoDO merchantReportInfo = channelMerchantAccessContext.getMerchantReportInfo();
        String requestId = merchantReportInfo.getRequestId();
        params.put("orig_client_trans_id", requestId);
        // 再提交数据
        CommonResult<BaoFuCommonRes> commonResult = baofuMerchantCommonParamsHandle.request(params, requestId, "2604", null, configCommonResult.getData(),
                channelMerchantAccessContext.isTest());
        if (!commonResult.isSuccess()) {
            channelMerchantAccessContext.setRemark(commonResult.getMsg());
            channelMerchantAccessContext.setProcessStatus(false);
            return;
        }
        BaoFuCommonRes baoFuCommonRes = commonResult.getData();
        String data = baoFuCommonRes.getData();
        if (!StringUtils.hasText(data)) {
            channelMerchantAccessContext.setRemark(baoFuCommonRes.getResp_msg());
            channelMerchantAccessContext.setProcessStatus(false);
            return;
        }
        BaoFuReportQueryRes baoFuReportQueryRes = JsonUtils.parseObject(data, BaoFuReportQueryRes.class);
        switch (baoFuReportQueryRes.getResult()) {
            case "FAIL":
                channelMerchantAccessContext.setRemark(baoFuReportQueryRes.getAudit_info());
                channelMerchantAccessContext.setProcessStatus(false);
                break;
            case "SUCCESS":
                merchantReportInfo.setSubMchId(baoFuReportQueryRes.getWallet_no());
                BaoFuReportExtentDto baoFuReportExtentDto = new BaoFuReportExtentDto();
                baoFuReportExtentDto.setAccountNo(baoFuReportQueryRes.getAccount_no());
                baoFuReportExtentDto.setHtAccountNo(baoFuReportQueryRes.getHtAccount_no());
                merchantReportInfo.setExtendA(JsonUtils.toJsonString(baoFuReportExtentDto));
                channelMerchantAccessContext.setReportStatus(MerchantEnum.REPORT_STATUS.WAIT_SIGN);
                channelMerchantAccessContext.setAuditStatus(MerchantEnum.REPORT_CHANNEL_CONFIG_STATUS.SMS_SEND);
                break;
            default:
                channelMerchantAccessContext.setReportStatus(MerchantEnum.REPORT_STATUS.CHANNEL_APPROVE);
        }

    }

    @Override
    public void merchantReportSign(ChannelMerchantReportSignContext channelMerchantReportSignContext) {
        CommonResult<BaoFuConfig> configCommonResult = baofuMerchantCommonParamsHandle.baoFuConfig(channelMerchantReportSignContext.getProviderChannelConfig(),
                channelMerchantReportSignContext.isTest());
        if (!configCommonResult.isSuccess()) {
            channelMerchantReportSignContext.setRemark(configCommonResult.getMsg());
            channelMerchantReportSignContext.setProcessStatus(false);
            return;
        }
        MerchantReportInfoDO merchantReportInfo = channelMerchantReportSignContext.getMerchantReportInfo();
        // 短信发送
        MerchantReportSmsSendDto merchantReportSmsSendDto = channelMerchantReportSignContext.getMerchantReportSmsSendDto();
        MerchantReportSmsCodeDto merchantReportSmsCodeDto = channelMerchantReportSignContext.getMerchantReportSmsCodeDto();
        if (merchantReportSmsSendDto != null) {
            Map<String, Object> params = new HashMap<>();
            String requestId = IdUtils.getSnowflakeNextIdStr();
            params.put("smsType", merchantReportSmsSendDto.getSmsType());
            params.put("walletNo", merchantReportInfo.getSubMchId());
            params.put("phone", merchantReportSmsSendDto.getPhone());
            PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
            channelMerchantReportSignContext.setPayChannelRequestDO(payChannelRequestDO);
            payChannelRequestDO.setRequestParams(JsonUtils.toJsonString(params));
            payChannelRequestDO.setRequestUrl("2127");
            // 再提交数据
            CommonResult<BaoFuCommonRes> commonResult = baofuMerchantCommonParamsHandle.request(params, requestId, "2127", null, configCommonResult.getData(),
                    channelMerchantReportSignContext.isTest());
            payChannelRequestDO.setResponse(JsonUtils.toJsonString(commonResult.getData()));
            if (!commonResult.isSuccess()) {
                channelMerchantReportSignContext.setRemark(commonResult.getMsg());
                channelMerchantReportSignContext.setProcessStatus(false);
                return;
            }
            BaoFuCommonRes baoFuCommonRes = commonResult.getData();
            String data = baoFuCommonRes.getData();
            if (!StringUtils.hasText(data)) {
                channelMerchantReportSignContext.setRemark(baoFuCommonRes.getResp_msg());
                channelMerchantReportSignContext.setProcessStatus(false);
                return;
            }
            BaoFuReportSmsRes baoFuReportQueryRes = JsonUtils.parseObject(data, BaoFuReportSmsRes.class);
            switch (baoFuReportQueryRes.getStatus()) {
                case "FAIL":
                    channelMerchantReportSignContext.setRemark(baoFuReportQueryRes.getAckMsg());
                    channelMerchantReportSignContext.setProcessStatus(false);
                    break;
                default:
            }
        }
        else {
            Map<String, Object> params = new HashMap<>();
            String requestId = IdUtils.getSnowflakeNextIdStr();
            params.put("smsCode", merchantReportSmsCodeDto.getSmsCode());
            params.put("smsType", merchantReportSmsCodeDto.getSmsType());
            params.put("walletNo", merchantReportInfo.getSubMchId());
            // 再提交数据
            CommonResult<BaoFuCommonRes> commonResult = baofuMerchantCommonParamsHandle.request(params, requestId, "2124", null, configCommonResult.getData(),
                    channelMerchantReportSignContext.isTest());
            if (!commonResult.isSuccess()) {
                channelMerchantReportSignContext.setRemark(commonResult.getMsg());
                channelMerchantReportSignContext.setProcessStatus(false);
                return;
            }
            BaoFuCommonRes baoFuCommonRes = commonResult.getData();
            String data = baoFuCommonRes.getData();
            if (!StringUtils.hasText(data)) {
                channelMerchantReportSignContext.setRemark(baoFuCommonRes.getResp_msg());
                channelMerchantReportSignContext.setProcessStatus(false);
                return;
            }
            BaoFuReportSmsRes baoFuReportQueryRes = JsonUtils.parseObject(data, BaoFuReportSmsRes.class);
            switch (baoFuReportQueryRes.getStatus()) {
                case "FAIL":
                    channelMerchantReportSignContext.setRemark(baoFuReportQueryRes.getAckMsg());
                    channelMerchantReportSignContext.setProcessStatus(false);
                    break;
                default:
            }
        }
    }

    @Override
    public MerchantReportCallBackDto submitReportCallBackParamsParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        MerchantReportCallBackDto merchantReportCallBackDto = new MerchantReportCallBackDto();
        CommonResult<BaoFuConfig> configCommonResult = baofuMerchantCommonParamsHandle.baoFuConfig(providerChannelConfigDO, true);
        if (!configCommonResult.isSuccess()) {
            merchantReportCallBackDto.setRemark(configCommonResult.getMsg());
            merchantReportCallBackDto.setProcessStatus(false);
            return merchantReportCallBackDto;
        }
        BaoFuConfig baoFuConfig = configCommonResult.getData();
        Map<String, String> params = HttpRequestUtil.requestFormParams(request);
        String results = JsonUtils.toJsonString(params);
        log.info("宝付机构开户结果通知 响应结果 results:{}", results);
        Boolean bool = baofuMerchantCommonParamsHandle.verifyByCerFile(results, baoFuConfig);
        if (!bool) {
            merchantReportCallBackDto.setVerifySign(false);
        }
        log.info("宝付机构开户结果通知 验签结果:" + bool);
        String response = null;
        try {
            response = BaoFuSigner.Base64Decode(params.get("data"));
        }
        catch (IOException e) {
            throw new RuntimeException(e);
        }
        BaoFuReportNotifyRes baoFuReportNotifyRes = JsonUtils.parseObject(response, BaoFuReportNotifyRes.class);
        if (baoFuReportNotifyRes.getAudit_status() == null) {
            merchantReportCallBackDto.setReportStatus(MerchantEnum.REPORT_STATUS.CHANNEL_APPROVE);
            return merchantReportCallBackDto;
        }
        merchantReportCallBackDto.setRequestId(params.get("client_trans_id"));
        switch (baoFuReportNotifyRes.getAudit_status()) {
            case "FAIL":
                merchantReportCallBackDto.setRemark(baoFuReportNotifyRes.getAudit_info());
                merchantReportCallBackDto.setProcessStatus(false);
                break;
            case "SUCCESS":
                merchantReportCallBackDto.setSubMchId(baoFuReportNotifyRes.getWallet_no());
                BaoFuReportExtentDto baoFuReportExtentDto = new BaoFuReportExtentDto();
                baoFuReportExtentDto.setAccountNo(baoFuReportNotifyRes.getAccount_no());
                baoFuReportExtentDto.setHtAccountNo(baoFuReportNotifyRes.getHtAccount_no());
                merchantReportCallBackDto.setExtendA(JsonUtils.toJsonString(baoFuReportExtentDto));
                merchantReportCallBackDto.setVirtualAccountNo(baoFuReportNotifyRes.getHtAccount_no());
                merchantReportCallBackDto.setReportStatus(MerchantEnum.REPORT_STATUS.APPROVE_SUCCESS);
                merchantReportCallBackDto.setAuditStatus(MerchantEnum.REPORT_CHANNEL_CONFIG_STATUS.SMS_SEND);
                break;
            default:
                merchantReportCallBackDto.setReportStatus(MerchantEnum.REPORT_STATUS.CHANNEL_APPROVE);
        }
        log.info("宝付机构开户结果通知 业务响应结果 response :{}", response);
        return merchantReportCallBackDto;
    }

    @Override
    public MerchantReportAmountCallBackDto reportAmountCallBackParamsParse(HttpServletRequest request) {
        MerchantReportAmountCallBackDto merchantReportAllotCallBackDto = new MerchantReportAmountCallBackDto();
        Map<String, String> params = HttpRequestUtil.requestFormParams(request);
        String response = null;
        try {
            response = BaoFuSigner.Base64Decode(params.get("data"));
        }
        catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        String results = JsonUtils.toJsonString(params);
        log.info("宝付电子户入金通知 响应结果 results:{}", results);
        merchantReportAllotCallBackDto.setCallBackBody(results);
        BaoFuReportAmountNotifyRes baoFuReportNotifyRes = JsonUtils.parseObject(response, BaoFuReportAmountNotifyRes.class);
        MerchantReportAmountDO merchantReportAmountDO = new MerchantReportAmountDO();
        merchantReportAmountDO.setAmount(MerchantUtils.fenToYuan(baoFuReportNotifyRes.getAmount()));
        merchantReportAmountDO.setRecordTime(DateUtils.shanghaiDate(baoFuReportNotifyRes.getRecord_time(), "yyyyMMddHHmmss"));
        merchantReportAmountDO.setRemark(baoFuReportNotifyRes.getRemark());
        merchantReportAmountDO.setPeerAccNo(baoFuReportNotifyRes.getPeer_acc_no());
        merchantReportAmountDO.setPeerAccName(baoFuReportNotifyRes.getPeer_acc_name());
        merchantReportAmountDO.setPeerBankNo(baoFuReportNotifyRes.getPeer_bank_no());
        merchantReportAmountDO.setPeerBankName(baoFuReportNotifyRes.getPeer_bank_name());
        merchantReportAmountDO.setAcctId(baoFuReportNotifyRes.getAcct_id());
        merchantReportAmountDO.setProcessStatus(MerchantEnum.REPORT_AMOUNT_STATUS.SUCCESS.getCode());
        merchantReportAllotCallBackDto.setMerchantReportAmount(merchantReportAmountDO);
        return merchantReportAllotCallBackDto;
    }

    @Override
    public CommonResult<MerchantReportAmountCallBackDto> reportAmountCallBackParamsParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        return null;
    }

    @Override
    public Boolean verifyCallBackParamsParse(String callBackBody, ProviderChannelConfigDO providerChannelConfigDO) {
        CommonResult<BaoFuConfig> configCommonResult = baofuMerchantCommonParamsHandle.baoFuConfig(providerChannelConfigDO, true);
        if (!configCommonResult.isSuccess()) {
            return false;
        }
        BaoFuConfig baoFuConfig = configCommonResult.getData();
        return baofuMerchantCommonParamsHandle.verifyByCerFile(callBackBody, baoFuConfig);
    }

    @Override
    public MerchantReportAllotCallBackDto reportAllotCallBackParamsParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        MerchantReportAllotCallBackDto merchantReportAllotCallBackDto = new MerchantReportAllotCallBackDto();
        CommonResult<BaoFuConfig> configCommonResult = baofuMerchantCommonParamsHandle.baoFuConfig(providerChannelConfigDO, true);
        if (!configCommonResult.isSuccess()) {
            merchantReportAllotCallBackDto.setRemark(configCommonResult.getMsg());
            merchantReportAllotCallBackDto.setProcessStatus(false);
            return merchantReportAllotCallBackDto;
        }
        BaoFuConfig baoFuConfig = configCommonResult.getData();
        Map<String, String> params = HttpRequestUtil.requestFormParams(request);
        String results = JsonUtils.toJsonString(params);
        log.info("宝付回调资金调拨结果通知 响应结果 results:{}", results);
        Boolean bool = baofuMerchantCommonParamsHandle.verifyByCerFile(results, baoFuConfig);
        if (!bool) {
            merchantReportAllotCallBackDto.setVerifySign(false);
        }
        log.info("宝付回调资金调拨结果通知 验签结果:" + bool);
        String response = null;
        try {
            response = BaoFuSigner.Base64Decode(params.get("data"));
        }
        catch (IOException e) {
            throw new RuntimeException(e);
        }
        merchantReportAllotCallBackDto.setRequestId(params.get("client_trans_id"));
        BaoFuReportAllotNotifyRes baoFuReportNotifyRes = JsonUtils.parseObject(response, BaoFuReportAllotNotifyRes.class);
        switch (baoFuReportNotifyRes.getStatus_msg()) {
            case "FAIL":
                merchantReportAllotCallBackDto.setRemark(baoFuReportNotifyRes.getStatus_msg());
                merchantReportAllotCallBackDto.setProcessStatus(false);
                break;
            case "SUCCESS":
                merchantReportAllotCallBackDto.setRealAmount(MerchantUtils.fenToYuan(baoFuReportNotifyRes.getReal_amount()));
                merchantReportAllotCallBackDto.setOrderAmount(MerchantUtils.fenToYuan(baoFuReportNotifyRes.getOrder_amount()));
                break;
            default:
        }
        log.info("宝付回调资金调拨结果通知 业务响应结果 response :{}", response);
        return merchantReportAllotCallBackDto;
    }

    @Override
    public void merchantReportAllot(ChannelMerchantReportBusContext channelMerchantReportBusContext) {
        CommonResult<BaoFuConfig> configCommonResult = baofuMerchantCommonParamsHandle.baoFuConfig(channelMerchantReportBusContext.getProviderChannelConfig(),
                channelMerchantReportBusContext.isTest());
        if (!configCommonResult.isSuccess()) {
            channelMerchantReportBusContext.setRemark(configCommonResult.getMsg());
            channelMerchantReportBusContext.setProcessStatus(false);
            return;
        }
        Map<String, Object> params = new HashMap<>();
        MerchantAppChannelDO merchantAppChannelDO = channelMerchantReportBusContext.getMerchantAppChannelDO();
        MerchantReportAmountDO merchantReportAmountDO = channelMerchantReportBusContext.getMerchantReportAmountDO();
        BoaFuAppChannelParams payAppChannelParams = payAppChannelParams(merchantAppChannelDO);
        params.put("wallet_no", payAppChannelParams.getWalletNo());
        params.put("order_amount", MerchantUtils.YuanToFen(merchantReportAmountDO.getAmount()));
        PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
        channelMerchantReportBusContext.setPayChannelRequestDO(payChannelRequestDO);
        payChannelRequestDO.setRequestParams(JsonUtils.toJsonString(params));
        payChannelRequestDO.setRequestUrl("2604");
        // 再提交数据
        CommonResult<BaoFuCommonRes> commonResult = baofuMerchantCommonParamsHandle.request(params, merchantReportAmountDO.getCode(), "2604", null, configCommonResult.getData(),
                channelMerchantReportBusContext.isTest());
        payChannelRequestDO.setResponse(JsonUtils.toJsonString(commonResult.getData()));
        if (!commonResult.isSuccess()) {
            channelMerchantReportBusContext.setRemark(commonResult.getMsg());
            channelMerchantReportBusContext.setProcessStatus(false);
            return;
        }
        BaoFuCommonRes baoFuCommonRes = commonResult.getData();
        String data = baoFuCommonRes.getData();
        if (!StringUtils.hasText(data)) {
            channelMerchantReportBusContext.setRemark(baoFuCommonRes.getResp_msg());
            channelMerchantReportBusContext.setProcessStatus(false);
            return;
        }
        BaoFuPaymentQueryRes baoFuReportQueryRes = JsonUtils.parseObject(data, BaoFuPaymentQueryRes.class);
        switch (baoFuReportQueryRes.getStatus()) {
            case "FAIL":
                channelMerchantReportBusContext.setRemark(baoFuReportQueryRes.getStatus_msg());
                channelMerchantReportBusContext.setProcessStatus(false);
                break;
            case "SUCCESS":
                break;
            default:
        }
    }

    @Override
    public void merchantReportAllotQuery(ChannelMerchantReportBusContext channelMerchantReportQueryContext) {
        log.info("宝付查询单笔代付 detailPaymentId:{}", channelMerchantReportQueryContext.getMerchantReportAmountDO().getCode());
        MerchantReportAmountDO merchantReportAmountDO = channelMerchantReportQueryContext.getMerchantReportAmountDO();
        CommonResult<BaoFuConfig> configCommonResult = baofuMerchantCommonParamsHandle.baoFuConfig(channelMerchantReportQueryContext.getProviderChannelConfig(),
                channelMerchantReportQueryContext.isTest());
        if (!configCommonResult.isSuccess()) {
            channelMerchantReportQueryContext.setRemark(configCommonResult.getMsg());
            channelMerchantReportQueryContext.setProcessStatus(false);
            return;
        }
        MerchantAppChannelDO merchantAppChannelDO = channelMerchantReportQueryContext.getMerchantAppChannelDO();
        BoaFuAppChannelParams payAppChannelParams = payAppChannelParams(merchantAppChannelDO);
        try {
            PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
            Map<String, Object> params = new HashMap<>();
            params.put("orig_client_trans_id", merchantReportAmountDO.getCode());
            payChannelRequestDO.setRequestParams(JsonUtils.toJsonString(params));
            // 再提交数据
            CommonResult<BaoFuCommonRes> commonResult = baofuMerchantCommonParamsHandle.request(params, merchantReportAmountDO.getCode(), "2207", null,
                    configCommonResult.getData(), channelMerchantReportQueryContext.isTest());
            payChannelRequestDO.setResponse(JsonUtils.toJsonString(commonResult));
            if (!commonResult.isSuccess()) {
                channelMerchantReportQueryContext.setRemark(commonResult.getMsg());
                channelMerchantReportQueryContext.setProcessStatus(false);
                return;
            }
            BaoFuCommonRes baoFuCommonRes = commonResult.getData();
            String data = baoFuCommonRes.getData();
            MerchantReportAmountDO updateTransferOrderDO = new MerchantReportAmountDO();
            channelMerchantReportQueryContext.setUdpateMerchantReportAmountDO(updateTransferOrderDO);
            if (!StringUtils.hasText(data)) {
                channelMerchantReportQueryContext.setRemark(baoFuCommonRes.getResp_msg());
                channelMerchantReportQueryContext.setProcessStatus(false);
                log.info("宝付查询单笔代付返回没有详情 直接失败 detailPaymentId:{}", channelMerchantReportQueryContext.getMerchantReportAmountDO().getCode());
                updateTransferOrderDO.setProcessStatus(MerchantEnum.PROCESS_STATUS.FAIL.getCode());
                channelMerchantReportQueryContext.setRemark(baoFuCommonRes.getResp_msg());
                return;
            }
            BaoFuPaymentQueryRes baoFuPaymentSubmitRes = JsonUtils.parseObject(data, BaoFuPaymentQueryRes.class);
            // INIT 初始化 PROCESSING处理中 SUCCESS成功 FAIL失败
            switch (baoFuPaymentSubmitRes.getStatus()) {
                case "FAIL":
                    updateTransferOrderDO.setProcessStatus(MerchantEnum.PROCESS_STATUS.FAIL.getCode());
                    break;
                case "SUCCESS":
                    updateTransferOrderDO.setProcessStatus(MerchantEnum.PROCESS_STATUS.SUCCESS.getCode());
                    updateTransferOrderDO.setRemark(baoFuPaymentSubmitRes.getStatus_msg());
                    break;
                default:
                    updateTransferOrderDO.setProcessStatus(MerchantEnum.PROCESS_STATUS.DOING.getCode());
            }

        }
        catch (Exception e) {
            channelMerchantReportQueryContext.setProcessStatus(false);
            channelMerchantReportQueryContext.setRemark(e.getMessage());
        }
    }

    @Override
    public void merchantReportAllotProof(ChannelMerchantReportBusContext channelMerchantReportQueryContext) {
        MerchantAppChannelDO merchantAppChannelDO = channelMerchantReportQueryContext.getMerchantAppChannelDO();
        log.info("宝付查询付款凭证 detailPaymentId:{}", merchantAppChannelDO.getCode());
        MerchantReportAmountDO merchantReportAmountDO = channelMerchantReportQueryContext.getMerchantReportAmountDO();
        CommonResult<BaoFuConfig> configCommonResult = baofuMerchantCommonParamsHandle.baoFuConfig(channelMerchantReportQueryContext.getProviderChannelConfig(),
                channelMerchantReportQueryContext.isTest());
        if (!configCommonResult.isSuccess()) {
            channelMerchantReportQueryContext.setRemark(configCommonResult.getMsg());
            channelMerchantReportQueryContext.setProcessStatus(false);
            return;
        }
        BoaFuAppChannelParams payAppChannelParams = payAppChannelParams(merchantAppChannelDO);
        try {
            PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
            Map<String, Object> params = new HashMap<>();
            params.put("orig_client_trans_id", merchantReportAmountDO.getCode());
            params.put("wallet_no", payAppChannelParams.getWalletNo());
            // 2-提现(宝付代付到银行卡)
            // 8-调拨(银行到宝付)
            // 4-银行入金
            params.put("type", "8");
            payChannelRequestDO.setRequestParams(JsonUtils.toJsonString(params));
            // 再提交数据
            CommonResult<BaoFuCommonRes> commonResult = baofuMerchantCommonParamsHandle.request(params, merchantReportAmountDO.getCode(), "2301", null,
                    configCommonResult.getData(), channelMerchantReportQueryContext.isTest());
            payChannelRequestDO.setResponse(JsonUtils.toJsonString(commonResult));
            if (!commonResult.isSuccess()) {
                channelMerchantReportQueryContext.setRemark(commonResult.getMsg());
                channelMerchantReportQueryContext.setProcessStatus(false);
                return;
            }
            BaoFuCommonRes baoFuCommonRes = commonResult.getData();
            String data = baoFuCommonRes.getData();
            if (!StringUtils.hasText(data)) {
                channelMerchantReportQueryContext.setRemark(baoFuCommonRes.getResp_msg());
                channelMerchantReportQueryContext.setProcessStatus(false);
                return;
            }
            BaoFuPaymentProofQueryRes baoFuPaymentSubmitRes = JsonUtils.parseObject(data, BaoFuPaymentProofQueryRes.class);
            // INIT 初始化 PROCESSING处理中 SUCCESS成功 FAIL失败
            switch (baoFuPaymentSubmitRes.getStatus()) {
                case "FAIL":
                    channelMerchantReportQueryContext.setProcessStatus(false);
                    channelMerchantReportQueryContext.setRemark("宝付获取凭证失败");
                    break;
                default:
                    byte[] bb = Base64.getDecoder().decode(baoFuPaymentSubmitRes.getContent());
                    byte[] ff = BaoFuFileZipUtil.unzip(bb);
                    channelMerchantReportQueryContext.setVoucherFileByte(ff);
            }
        }
        catch (Exception e) {
            channelMerchantReportQueryContext.setProcessStatus(false);
            channelMerchantReportQueryContext.setRemark(e.getMessage());
        }
    }

    @Override
    public void merchantReportSignQuery(ChannelMerchantReportQueryContext channelMerchantReportQueryContext) {

    }

    @Override
    public void queryChannelAccount(ChannelVirtualAccountContext channelVirtualAccountContext) {

    }

    @Override
    public void getMerchantReportSign(ChannelMerchantReportSignContext channelMerchantReportSignContext) {

    }

    @Override
    public String callBackResponse(CommonResult commonResult) {
        if (commonResult.isSuccess()) {
            return "{\"code\":\"SUCCESS\",\"message\":\"执行成功\"}";
        }
        else {
            return "{\"code\":\"FAIL\",\"message\":\"+" + commonResult.getMsg() + "\"}";
        }
    }

    CommonResult<BaoFuCommonRes> uploadFile(ChannelMerchantReportContext channelMerchantReportContext, BaoFuConfig baoFuConfig) {
        CommonResult<File> fileCommonResult = baoFuMerchantParamsHandle.zipFile(channelMerchantReportContext.getMerchantReportDto());
        if (!fileCommonResult.isSuccess()) {
            return CommonResult.error(fileCommonResult.getCode(), fileCommonResult.getMsg());
        }
        Map<String, File> fileMap = new HashMap<>();
        File file = fileCommonResult.getData();
        fileMap.put("file", file);
        return baofuMerchantCommonParamsHandle.requestFile(fileMap, IdUtils.getSnowflakeNextIdStr(), "2107", channelMerchantReportContext.getNotifyUrl(), baoFuConfig,
                channelMerchantReportContext.isTest());
    }

    private BoaFuAppChannelParams payAppChannelParams(MerchantAppChannelDO merchantAppChannelDO) {
        return JsonUtils.parseObject(merchantAppChannelDO.getAppConfigJson(), BoaFuAppChannelParams.class);
    }
}
